import axios from "axios";
import store from "../store/index.js";
import * as Types from "@/store/action-types.js";
class HttpRequest {
  constructor() {
    this.baseURL =
      process.env.NODE_ENV === "production" ? "/" : "http://localhost:7001";
    this.timeout = 3000;
    // loading 需要加
    this.queue = {}; // 专门用来维护请求队列的
    // 页面切换 我需要请求请求
  }

  setInterceptor(instance, url) {
    instance.interceptors.request.use((config) => {
      // 可以记录请求的取消函数
      // 开启loading 自己找个地方显示下
      if (Object.keys(this.queue).length == 0) {
        //  a --> loading  好了，  b--> loading 还未结束， 这是不应该结束loading， 通过this.queue控制里面有没有值， 如果有值就继续loading， 如果没值就结束loading
        // 开启loading
      }
      let token = localStorage.getItem("token");
      if (token) {
        // 每次请求都会携带一个权限访问 到服务器
        config.headers.authorization = token;
      }
      let CancelTokenSelf = axios.CancelToken;
      // xhr.abort()  中断请求方法
      config.cancelToken = new CancelTokenSelf((c) => {
        // console.log(c);
        // c就是当前取消请求的token
        // c可以存到vuex中， 页面切换的时候 组件销毁的就是执行
        store.commit(Types.SET_TOKEN, c); // 同步将取消方法存入到vuex中
      });
      this.queue[url] = true;

      return config; // 只是扩展请求的配置
    });

    instance.interceptors.response.use(
      (res) => {
        delete this.queue[url]; // 一旦响应了， 就从队列中删除
        if (Object.keys(this.queue).length == 0) {
          // close loading
        }
        if (res.data.err == 0) {
          return res.data.data; // 接口里面可以配合 switchcase状态码 判断各种状态
        } else {
          return Promise.reject(res.data); // 失败抛出异常
        }
      },
      (err) => {
        delete this.queue[url];
        if (Object.keys(this.queue).length == 0) {
          // close loading
        }
        return Promise.reject(err);
      }
    );
  }

  request(options) {
    // 通过request方法来进行请求操作
    // 每次请求可以创建一个新的实例， 如果业务不复杂你可以不创建实例 直接使用axios
    let instance = axios.create(); // 实例  new Axios

    let config = {
      baseURL: this.baseURL,
      timeout: this.timeout,
      ...options,
    };
    this.setInterceptor(instance, config.url);
    return instance(config); // 产生的是一个 promise  axios()
  }

  get(url, data = {}) {
    // url, {}
    // axios.get("/xxx", {params:xxx})
    return this.request({
      url,
      method: "get",
      ...data,
    });
  }

  post(url, data = {}) {
    // axios.post("/xxx", {data})
    return this.request({
      url,
      method: "post",
      data,
    });
  }
}

// a/b 用的是同一个实例
// a 里面的请求有独立的拦截器
// b 里面也有拦截器

export default new HttpRequest();
